
#pragma once

#include <list>
#include "../HtmlGenerator/GameLogic.h"
#include "../HtmlGenerator/UriParser.h"

//Contains and manages all started games.
class GameBase
{
	private:
		static GameBase *ref;
	private:
		std::list<Game *> _games;	//List of all games.
		Game *_unstarted;			//Reference to current unstarted game (or NULL).
		//Creates empty GameBase.
		inline GameBase()
		{ _unstarted = NULL; }
	public:
		//Processes received request. Returns required game and player (request sender).
		//In case of error throws std::exception().
		void ProcessRequest(UriParser &params, Game *&game, Player &player)
		{
			size_t val;
			if (params.GetIntArgument("game", val))
			{
				//Finding existent game.
				game = NULL;
				std::list<Game *>::iterator it = _games.begin();
				while (it != _games.end())
					if ((size_t)*it == val)
					{
						game = *it;
						break;
					}
					else
						it++;
				if (game == NULL)
					throw std::runtime_error("Cannot find corresponded game");
				//Getting player.
				size_t pl;
				if (!params.GetIntArgument("player", pl))
					throw std::runtime_error("Cannot get player ID");
				player = (Player)pl;
				//Applying action.
				size_t x, y;
				if (params.GetIntArgument("x", x) &&
					params.GetIntArgument("y", y))
					game->ApplyAction(GameAction(player, x, y));
			}
			else
			{
				//It's request for new game.
				const char *name;
				size_t width, height;
				if (!params.GetStringArgument("user_name", name) ||
					!params.GetIntArgument("size_x", width) ||
					!params.GetIntArgument("size_y", height))
					throw std::runtime_error("Not enough info for new game");
				if (_unstarted == NULL)
				{
					//Creating new unstarted game.
					_unstarted = new Game(width, height, name);
					_games.push_back(_unstarted);
					game = _unstarted;
					player = Player1;
				}
				else
				{
					//Adding second player to unstarted game.
					_unstarted->GetInfo().SetPlayer2(name);
					game = _unstarted;
					player = Player2;
					_unstarted = NULL;
				}
			}
		}

		static inline GameBase *GetRef()
		{ return ref; }
};
